<style>
  .component-upload input {
    width: 1px;
    height: 1px;
    overflow: hidden;
    position: absolute;
  }
  .component-upload img {
    max-width: 200px;
  }
  .component-pagination {
    font-size: 14px;
    padding: 16px 0;
    display: flex;
    line-height: 34px;
  }
  .component-pagination .pagination-info {
    justify-content: center;
    padding-left: 8px;
  }
  .list-select table {
    margin-top: 8px;
  }
  .list-select .component-pagination {
    padding: 0;
  }
  .list-select .pagination-info {
    font-size: 12px;
  }
  .list-select td {
    padding: 0 !important;
  }
  .list-select input[type="radio"] {
    margin: 0.3rem;
  }
  .list-select td>label {
    width: 100%;
    height: 100%;
    padding: 0.3rem !important;
    font-weight: normal !important;
  }
  .tag-editor table {
    width: 100%;
    margin-top: 8px;
  }
  .tag-editor table td {
    padding: 4px 8px;
  }
  .tag-editor table td div {
    padding: 4px;
  }
  .datetime-picker .date-picker {
    display: inline-block;
    width: 7rem;
  }
  .datetime-picker .date-picker input {
    width: 100%;
  }
  .datetime-picker .form-control {
    display: inline-block;
    width: 3rem;
  }

  .modal-full {
    width: 100% !important;
    max-width: 100% !important;
  }
  .modal-full .modal-content {
    position: fixed;
    top: 0;
    height: 100% !important;
    width: 100% !important;
    background: white !important;
    border: 0;
  }
  .modal-full iframe {
    width: 100%;
    height: 100%;
  }
  .modal-full .modal-body {
    padding: 0 !important;
  }
  .remote-page {
    position: fixed;
    left: 0;
    top: 0;
    height: 100%;
    width: 100%;
    z-index: 10000;
    background: white;
  }
  .remote-page iframe {
    height: 100%;
    width: 100%;
    border: 0;
  }
  .remote-page .loading-box {
    text-align: center;
    padding: 80px;
  }
  .simditor-toolbar {
    width: 100% !important;
  }
</style>

<template id="remote-page-template">
  <div class="remote-page">
    <div v-show="loading" class="loading-box">
      <div class="loading"></div>
    </div>
    <iframe :src="url" ref="iframe"></iframe>
  </div>
</template>

<template id="modal-template">
  <div class="modal fade" :id="this.id">
    <div class="modal-dialog" :class="this.size ? 'modal-' + this.size : ''">
      <div class="modal-content">
        <div class="modal-header" v-if="typeof showHeader === 'undefined' || showHeader">
          <h5 class="modal-title">{{this.title}}</h5>
          <button type="button" class="close" data-dismiss="modal" aria-label="Close">
            <span aria-hidden="true">&times;</span>
          </button>
        </div>
        <div class="modal-body">
          <slot name="content" />
        </div>
        <div class="modal-footer" v-if="typeof showFooter === 'undefined' || showFooter">
          <button type="button" class="btn btn-primary btn-sm" @click="$emit('ok', ok())" :disabled="this.loading">确定</button>
          <button type="button" class="btn btn-default btn-sm" data-dismiss="modal" :disabled="this.loading">取消</button>
        </div>

      </div>
      <!-- /.modal-content -->
    </div>
    <!-- /.modal-dialog -->
  </div>
</template>


<template id="datepicker-template">
  <div class="input-group date date-picker" data-provide="datepicker" data-date-format="yyyy-mm-dd" data-date-language="zh-CN">
    <input
      type="text" class="form-control form-control-sm"
      @blur="ok"
      :value="value"
      :placeholder="this.placeholder" />
    <div class="input-group-addon">
      <span class="glyphicon glyphicon-th"></span>
    </div>
  </div>
</template>

<template id="datetimepicker-template">
  <div class="datetime-picker">
    <datepicker
      v-model="datetime.date"
      @input="handleChange"></datepicker>
    <select
      @input="handleChange"
      class="form-control-sm" v-model="datetime.hour" >
      <option v-for="hour in hours" :value="hour" v-text="hour"></option>
    </select>
    <span>:</span>
    <select
      @input="handleChange"
      class="form-control-sm"  v-model="datetime.minute">
      <option v-for="minute in minutes" :value="minute" v-text="minute"></option>
    </select>
    <span>:</span>
    <select
      @input="handleChange"
      class="form-control-sm"  v-model="datetime.second">
      <option v-for="second in minutes" :value="second" v-text="second"></option>
    </select>
  </div>
</template>

<template id="form-item-template">
  <div :class="this.type !== 'hidden' ? 'form-group row' : ''">
    <input type="hidden" v-if="this.type === 'hidden'" v-model="this.value" />
    <label class="col-sm-3 col-form-label" v-if="this.type !== 'hidden'">{{this.label}}</label>
    <div class="col-sm-9" v-if="['hidden', 'switch', 'image', 'imageshow' ,'radios', 'select', 'textarea', 'editor', 'region', 'datetimepicker',  'datepicker', 'list-select', 'group-list-select', 'tag-editor'].indexOf(this.type) === -1">
      <input
        :placeholder="this.placeholder"
        :type="this.type ? this.type : 'text'" class="form-control" v-model="this.value" @input="handleChange" />
    </div>
    <div class="col-sm-9" v-if="this.type === 'image'">
      <upload v-model="this.value" :tip="this.tip" @input="handleUpload" accept=".jpg,.png"></upload>
    </div>
      <div class="col-sm-9" v-if="this.type === 'imageshow'">
          <div class="component-upload" v-if="this.value">
              <img :src="this.value" />
          </div>
      </div>
    <div class="col-sm-9" v-if="this.type === 'radios'">
      <div class="btn-group btn-group-toggle">
        <label class="btn btn-sm" :class="option.value == value ? 'btn-primary active' : 'btn-default'" v-for="option in this.options">
          <input type="radio" :name="'options-' + name" :value="option.value" v-model="value" @change="handleChange" /> {{option.label}}
        </label>
      </div>
    </div>
    <div class="col-sm-9" v-if="this.type === 'textarea'">
      <textarea class="form-control" v-model="this.value" @input="handleChange"></textarea>
    </div>
    <div class="col-sm-9" v-if="this.type === 'editor'">
      <editor v-model="this.value" @input="handleChange"></editor>
    </div>
    <div class="col-sm-9" v-if="this.type === 'switch'">
      <div class="btn-group btn-group-toggle">
        <label class="btn btn-primary btn-sm" :class="{1: 'active'}[this.value]">
          <input type="radio" :name="'options-' + this.name" :value="1" v-model="this.value" @change="handleChange" /> 是
        </label>
        <label class="btn btn-primary btn-sm" :class="{0: 'active'}[this.value]">
          <input type="radio" :name="'options-' + this.name" :value="0" v-model="this.value" @change="handleChange" /> 否
        </label>
      </div>
    </div>
    <div class="col-sm-9"  v-if="this.type === 'region'">
      <region-select
        v-model="this.value"
        @input="handleChange"></region-select>
    </div>
    <div class="col-sm-9"  v-if="this.type === 'list-select'">
      <list-select
        v-model="this.value"
        :config="this.config"
        @input="handleChange"></list-select>
    </div>

    <div class="col-sm-9"  v-if="this.type === 'group-list-select'">
      <div v-for="(option, index) in this.groupConfig.options" v-if="groupTrigger == option.value">
        <list-select
          v-model="value"
          :config="groupConfig.groups[index]"
          @input="handleChange"></list-select>
      </div>
    </div>

    <div class="col-sm-9"  v-if="this.type === 'datetimepicker'">
      <datetimepicker
        v-model="this.value"
        @input="handleChange"></datetimepicker>
    </div>

    <div class="col-sm-9"  v-if="this.type === 'datepicker'">
      <datepicker
        v-model="this.value"
        @input="handleChange"></datepicker>
    </div>

    <div class="col-sm-9"  v-if="this.type === 'tag-editor'">
      <tag-editor
        v-model="this.value"
        @input="handleChange"></tag-editor>
    </div>

    <div class="col-sm-9" v-if="this.type === 'select'">
      <select v-model="this.value" class="form-control" @change="handleChange" >
        <option v-for="o in this.options" v-text="o.label" :value="o.value"></option>
      </select>
    </div>

  </div>
</template>


<template id="upload-template">
<div class="component-upload">
  <label class="btn btn-primary bn-sm" :class="{true: 'disabled'}[!!progress]">
    <span>上传</span>
    <span v-if="progress" v-text="progress"></span>
    <input type="file" @change="upload" :disabled="!!progress" :accept="accept" />
  </label>
    <label v-text="tip"></label>
  <div v-if="image" >
    <img :src="image" />
    <button type="button" class="btn btn-danger btn-sm" @click="remove">删除</button>
  </div>
</div>
</template>

<template id="pagination-template">
    <nav class="pagination-wrapper">
        <div class="f1" v-text="'总共 ' + totalCount + ' 条记录'"></div>
        <div class="f1 align-right">
            <ul class="pagination">
                <li @click="prevPage()" v-if="currentPage > 1 && pageCount > 10">
                    <a href="#" aria-label="Previous"><span aria-hidden="true">«</span></a>
                </li>
                <li @click="change(p)" class="page-item" v-for="p in pages" :class="currentPage == p ? 'active' : ''">
                    <a href="#" v-text="p">1</a>
                </li>
                <li @click="nextPage()" v-if="currentPage < pageCount && pageCount > 10">
                    <a aria-label="Next"><span aria-hidden="true">»</span></a>
                </li>
            </ul>
        </div>
    </nav>
</template>

<template id="region-select-template">
<div>
  <select
    class="form-control"
    style="width: 120px; display: inline-block;"
    v-model="selectedCityId"
    @change="handleCityChange">
    <option value="0">请选择</option>
    <option v-for="city in regions" v-text="city.name" :value="city.id"></option>
  </select>
  <select
    class="form-control"
    style="width: 120px; display: inline-block;"
    v-model="selectedDistrictId"
    @change="handleDistrictChange">
    <option value="0">请选择</option>
    <option v-for="district in districts" v-text="district.name" :value="district.id"></option>
  </select>
</div>
</template>

<template id="list-select-template">
  <div class="list-select">
    <div class="form-control">
      {{selectedValue}}
    </div>
    <table class="table table-sm table-bordered">
      <thead>
      <tr>
        <th>选择</th>
        <th v-for="field in config.fields" v-text="field.name"></th>
      </tr>
      </thead>
      <tbody>
      <tr v-for="item in list">
        <td>
          <input
            @change="handleInput"
            :id="'list_select_' + config.idField + '_' + item[config.idField]"
            type="radio"
            v-model="selectedValue"
            :name="'list_select_' + config.idField" :value="item[config.idField]" />
        </td>
        <td v-for="field in config.fields">
          <label :for="'list_select_' + config.idField + '_' + item[config.idField]" v-text="item[field.key]"></label>
        </td>
      </tr>
      </tbody>
    </table>
    <pagination :current-page="currentPage" :page-count="pageCount" :total-count="totalCount" @change="changePage"></pagination>
  </div>
</template>


<template id="tag-editor-template">
  <div class="tag-editor">
    <select v-model="form.color">
      <option v-for="color in colors" v-text="color"></option>
    </select>
    <input type="text" v-model="form.value" placeholder="标签内容" />
    <button type="button" class="btn btn-sm btn-primary" @click="add">添加</button>

    <table>
      <tbody>
      <tr v-for="(item, index) in items">
        <td>
          <div v-text="item.value" :style="'background-color: ' + item.color"></div>
        </td>
        <td>
          <button type="button" class="btn btn-sm btn-primary" @click="remove(index)">删除</button>
        </td>
      </tr>
      </tbody>
    </table>
  </div>
</template>

<template id="editor-template">
  <textarea ref="doc" style="height: 6em;"></textarea>
</template>

<template id="neditor-template">

</template>

<script>
  Vue.component('pagination', {
    template: '#pagination-template',
    props: ['current-page', 'page-count', 'total-count'],
    data: function () {
      return {
      };
    },
    computed: {
      pages: function () {
        var size = 10;
        var pages = [];
        if (this.pageCount > size) {
          var start = parseInt(this.currentPage - size / 2);
          var end = parseInt(this.currentPage + size / 2);
          if (start < 1) {
            end -= start;
            start = 1;
          }
          if (end > this.pageCount) {
            end = this.pageCount;
          }
          if (start > 1) {
            pages.push(1);
          }
          if (start > 2) {
            pages.push('...');
          }
          for (var i = start; i <= end; i++) {
            pages.push(i);
          }
          if (end < this.pageCount - 1) {
            pages.push('...');
          }
          if (end < this.pageCount) {
            pages.push(this.pageCount);
          }
        } else {
          for (var i = 1; i <= this.pageCount; i++) {
            pages.push(i);
          }
        }
        return pages;
      }
    },
    methods: {
      prevPage: function () {
        this.change(this.currentPage - 1);
      },
      nextPage: function () {
        this.change(this.currentPage + 1);
      },
      change: function (currentPage) {
        this.currentPage = currentPage;
        this.$emit('change', currentPage);
      }
    }
  });
  Vue.component('upload', {
    template: '#upload-template',
    props: ['value', 'accept', 'tip'],
    data: function () {
      return {
        progress: '',
        image: '',
        accept: this.accept ? this.accept : 'image/*'
      };
    },
    watch: {
      value: function () {
        if (typeof this.value !== 'undefined') {
          this.image = this.value;
        }
      }
    },
    methods: {
      remove: function () {
        this.image = '';
        this.$emit('input', '');
      },
      upload: function (e) {
        var self = this;
        if (!e.target.files.length) {
          return;
        }
        var target = e.target;
        var file = target.files[0];
        var form = new FormData();
        form.append('file', file);
        $.ajax({
          url: this.url ? this.url : '/api/upload/file',
          type: "POST",
          dataType: 'json',
          data: form,
          cache: false,
          processData: false,
          contentType: false,
          xhr: function() {
            var xhr = new XMLHttpRequest();
            xhr.upload.addEventListener('progress', function (e) {
              var progress = (e.loaded / e.total) * 100;
              if (progress >= 99) {
                progress = 90;
              }
              self.progress = progress;
              self.$emit('progress', self.progress);
            });
            return xhr;
          },
          success: function (data) {
            self.progress = '';
            target.value = '';
            self.image = data.url;
            self.$emit('input', data.url);
          },
          error: function (e) {
            self.progress = '';
            target.value = '';
            console.log(e);
          }
        });

      }
    }
  });

  Vue.component('modal', {
    template: '#modal-template',
    props: ['id', 'title', 'loading', 'show-header', 'show-footer', 'size'],
    mounted: function () {
      console.log(this.title, this.size)
    },
    methods: {
      ok: function () {
        var id = '#' + this.id;
        return {
          close: function () {
            $(id).modal('hide');
          }
        };
      }
    }
  });

  Vue.component('datepicker', {
    template: '#datepicker-template',
    props: ['id', 'placeholder', 'value'],
    methods: {
      ok: function () {
        this.$emit('input', event.target.value);
      }
    }
  });
  Vue.component('datetimepicker', {
    template: '#datetimepicker-template',
    props: ['id', 'placeholder', 'value'],
    data: function () {
      var hours = [];
      var minutes = [];
      for (var i = 0; i < 24; i++) {
        hours.push(i < 10 ? '0' + i : '' + i);
      }
      for (var i = 0; i < 60; i++) {
        minutes.push(i < 10 ? '0' + i : '' + i);
      }
      return {
        hours: hours,
        minutes: minutes,
        datetime: this.createDateTime(this.value)
      };
    },
    watch: {
      value: function (newValue) {
        console.log('newValue', newValue)
        this.datetime = this.createDateTime(newValue);
        console.log('this.datetime', this.datetime);
      }
    },
    methods: {
      createDateTime: function (value) {
        var items = value ? value.split(' ') : [];
        var times = items.length ? items[1].split(':') : [];
        return {
          date: items.length ? items[0] : '',
          hour: times.length ? times[0] : '00',
          minute: times.length ? times[1] : '00',
          second: times.length && times[2] ? times[2] : '00'
        }
      },
      handleChange: function () {
        var datetime = this.datetime;
        var self = this;
        setTimeout(function () {
          var result = datetime.date + ' ' + datetime.hour + ':' + datetime.minute + ':' + datetime.second;
          self.$emit('input', result);
        }, 100);
      }
    }
  });

  Vue.component('form-item', {
    template: '#form-item-template',
    props: ['label', 'type', 'value', 'tip', 'placeholder', 'name', 'options', 'config', 'group-config', 'group-trigger'],
    methods: {
        handleChange: function (e) {
          console.log('form item chage:', e);
          this.$emit('input', e.target ? e.target.value : e);
        },
        handleUpload: function (value) {
          this.$emit('input', value);
        }
    }
  });

  (function () {
    var regions =
      [{"id":"1","name":"\u6d77\u53e3\u5e02","children":[{"id":"3","name":"\u79c0\u82f1\u533a"},{"id":"4","name":"\u9f99\u534e\u533a"},{"id":"5","name":"\u743c\u5c71\u533a"},{"id":"6","name":"\u7f8e\u5170\u533a"}]},{"id":"2","name":"\u4e09\u4e9a\u5e02","children":[{"id":"7","name":"\u6d77\u68e0\u533a"},{"id":"8","name":"\u5409\u9633\u533a"},{"id":"9","name":"\u5929\u6daf\u533a"},{"id":"10","name":"\u5d16\u5dde\u533a"}]}];

    Vue.component('region-select', {
      template: '#region-select-template',
      props: ['value'],
      data: function () {
        return {
          regions: regions,
          selectedCityId: 0,
          selectedDistrictId: 0
        };
      },
      watch: {
        value: function (newValue) {
          this.selectedCityId = newValue[0];
          this.selectedDistrictId = newValue[1];
        }
      },
      computed: {
        districts: function () {
          if (this.selectedCityId == 0) {
            return [];
          }
          for (var i = 0; i < regions.length; i++) {
            if (regions[i].id == this.selectedCityId) {
              return regions[i].children;
            }
          }
          return [];
        }
      },
      methods: {
        handleCityChange: function (e) {
          this.$emit('inputCity', e.target.value);
          this.selectedDistrictId = 0;
        },
        handleDistrictChange: function (e) {
          this.$emit('input', [this.selectedCityId, e.target.value]);
        }
      }
    });
  })();

  Vue.component('list-select', {
    template: '#list-select-template',
    props: ['value', 'config'],
    mounted: function () {
      console.log(this.config, 'this.config')
      if (this.config) {
        this.getList();
      }
    },
    data: function () {
      var filter = $.extend({
        page_size: 10
      }, this.config.params);
      return {
        selectedValue: this.value ? this.value : 0,
        currentPage: 1,
        totalCount: 0,
        pageCount: 0,
        list: [],
        filter: filter
      }
    },
    watch: {
      value: function (newValue) {
        this.selectedValue = newValue;
      },
      config: function (newVale) {
        this.list = [];
        this.filter = $.extend({
          page_size: 10
        }, this.config.params);
        this.getList();
      }
    },
    methods: {
      getList: function () {
        var self = this;
        $.get('/api/' + this.config.module + '/index', this.filter, function (res) {
          self.totalCount = res._meta.totalCount;
          self.pageCount = res._meta.pageCount;
          self.currentPage = res._meta.currentPage;
          self.list = res.items;
        });
      },
      handleInput: function (e) {
        console.log(e.target.value, 'handleInput')
        this.$emit('input', e.target.value);
      },
      changePage: function (page) {
        this.filter.page = page;
        this.getList();
      }
    }
  });

  Vue.component('tag-editor', {
    template: '#tag-editor-template',
    props: ['value'],
    data: function () {
      var colors = ['red', 'green', 'yellow', 'orange', 'black'];
      var d = {
        form: {
          color: colors[0],
          value: ''
        },
        items: this.value ? this.value : [],
        colors: colors
      };
      return d;
    },
    watch: {
      value: function (newValue) {
        this.items = newValue ? newValue : [];
      }
    },
    methods: {
      add: function () {
        var value = $.trim(this.form.value);
        if (!value) {
          return;
        }
        this.items.push({
          color: this.form.color,
          value: value
        });
        this.$emit('input', this.items);
        this.form.value = '';
      },
      remove: function (index) {
        this.items.splice(index, 1);
      }
    }
  });

  Vue.component('editor', {
    template: '#editor-template',
    props: ['value','content'],
    data: function () {
      return {
        editor: null,
        editorHandler: null,
        editing: false,
      }
    },
    mounted: function () {
        // alert(this.content);
      this.editor = new Simditor({
        textarea: this.$refs.doc,
        toolbar: [
          'title',
          'bold',
          'italic',
          'underline',
          //'strikethrough',
          'fontScale',
          'color',
          //'ol',
          //'ul',
          //'blockquote',
          //'code',
          'table',
          'link',
          'image',
          //'hr',
          'indent',
          'outdent',
          'alignment'
        ]
      });
      var self = this;
        self.editor.setValue(self.content);
      this.editor.on('valuechanged', function (e, src) {
        self.editing = true;
        self.$emit('input', self.editor.getValue());
      });
    },
    watch: {
      value: function (newVal) {
        if (!this.editing && this.editor) {
          this.editor.setValue(newVal ? newVal : '');
        }
        this.editing = false;
      }
    },
    methods: {
    }
  });

  Vue.component('remote-page', {
    template: '#remote-page-template',
    props: ['url'],
    data: function () {
      return {
        loading: true
      };
    },
    mounted: function () {
      var self = this;
      this.$refs.iframe.onload = function () {
        self.loading = false;
      };
    },
    watch: {
      url: function (newValue) {
        this.loading = true;
        this.$refs.iframe.contentDocument.body.innerHTML = '';
      }
    },
    methods: {

    }
  })
</script>